home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Python 1.4 / Python 1.4 source / Mac / Python / macgetpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-22  |  10.5 KB  |  402 lines  |  [TEXT/CWIE]

  1. #include "Python.h"
  2. #include "osdefs.h"
  3. #include "macglue.h"
  4. #include "pythonresources.h"
  5.  
  6.  
  7. /* Return the initial python search path.  This is called once from
  8. ** initsys() to initialize sys.path.
  9. **
  10. ** If USE_BUILTIN_PATH is defined the path defined here is used
  11. ** (after prepending the python home dir to each item).
  12. ** If it is not defined the path is gotten from a resource in the
  13. ** Preferences file.
  14. **
  15. ** XXXX This code needs cleaning up. The routines here have moved
  16. ** around quite a bit, and they're pretty messy for that reason.
  17. */
  18.  
  19. #include <Files.h>
  20. #include <Aliases.h>
  21. #include <Folders.h>
  22. #include <Resources.h>
  23. #include <TextUtils.h>
  24. #include <Dialogs.h>
  25.  
  26. #ifdef USE_GUSI
  27. #include <GUSI.h>
  28. #endif
  29.  
  30. #define PYTHONPATH "\
  31. :\n\
  32. :Lib\n\
  33. :Lib:stdwin\n\
  34. :Lib:test\n\
  35. :Lib:mac"
  36.  
  37. static void
  38. getpreffilefss(FSSpec *fssp)
  39. {
  40.     static int diditbefore=0;
  41.     static FSSpec fss;
  42.     short prefdirRefNum;
  43.     long prefdirDirID;
  44.     Handle namehandle;
  45.     
  46.     if ( !diditbefore ) {
  47.         if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
  48.                         &prefdirDirID) != noErr ) {
  49.             /* Something wrong with preferences folder */
  50.             (void)StopAlert(NOPREFDIR_ID, NULL);
  51.             exit(1);
  52.         }
  53.         
  54.         if ( (namehandle=GetNamedResource('STR ', PREFFILENAME_NAME)) == NULL ) {
  55.             (void)StopAlert(NOPREFNAME_ID, NULL);
  56.             exit(1);
  57.         }
  58.         
  59.         HLock(namehandle);
  60.         (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, (unsigned char *)*namehandle, &fss);
  61.         HUnlock(namehandle);
  62.         ReleaseResource(namehandle);
  63.         diditbefore = 1;
  64.     }
  65.     *fssp = fss;
  66. }
  67.  
  68. char *
  69. Py_GetPath()
  70. {
  71.     /* Modified by Jack to do something a bit more sensible:
  72.     ** - Prepend the python home-directory (which is obtained from a Preferences
  73.     **   resource)
  74.     ** - Add :
  75.     */
  76.     static char *pythonpath;
  77.     char *p, *endp;
  78.     int newlen;
  79.     char *curwd;
  80.     staticforward char *PyMac_GetPythonDir();
  81. #ifndef USE_BUILTIN_PATH
  82.     staticforward char *PyMac_GetPythonPath();
  83. #endif
  84.     
  85.     if ( pythonpath ) return pythonpath;
  86. #ifndef USE_BUILTIN_PATH
  87.     if ( pythonpath = PyMac_GetPythonPath() )
  88.         return pythonpath;
  89.     printf("Warning: No pythonpath resource found, using builtin default\n");
  90. #endif
  91.     curwd = PyMac_GetPythonDir();
  92.     p = PYTHONPATH;
  93.     endp = p;
  94.     pythonpath = malloc(2);
  95.     if ( pythonpath == NULL ) return PYTHONPATH;
  96.     strcpy(pythonpath, ":");
  97.     while (*endp) {
  98.         endp = strchr(p, '\n');
  99.         if ( endp == NULL )
  100.             endp = p + strlen(p);
  101.         newlen = strlen(pythonpath) + 1 + strlen(curwd) + (endp-p);
  102.         pythonpath = realloc(pythonpath, newlen+1);
  103.         if ( pythonpath == NULL ) return PYTHONPATH;
  104.         strcat(pythonpath, "\n");
  105.         if ( *p == ':' ) {
  106.             p++;
  107.             strcat(pythonpath, curwd);
  108.             strncat(pythonpath, p, (endp-p));
  109.             newlen--;   /* Ok, ok, we've allocated one byte too much */
  110.         } else {
  111.             /* We've allocated too much in this case */
  112.             newlen -= strlen(curwd);
  113.             pythonpath = realloc(pythonpath, newlen+1);
  114.             if ( pythonpath == NULL ) return PYTHONPATH;
  115.             strncat(pythonpath, p, (endp-p));
  116.         }
  117.         pythonpath[newlen] = '\0';
  118.         p = endp + 1;
  119.     }
  120.     return pythonpath;
  121. }
  122.  
  123.  
  124. /*
  125. ** Open/create the Python Preferences file, return the handle
  126. */
  127. static short
  128. PyMac_OpenPrefFile()
  129. {
  130.     AliasHandle handle;
  131.     FSSpec dirspec;
  132.     short prefrh;
  133.     OSErr err;
  134.  
  135.     getpreffilefss(&dirspec);
  136.     prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  137.     if ( prefrh < 0 ) {
  138. #if 0
  139.         action = CautionAlert(NOPREFFILE_ID, NULL);
  140.         if ( action == NOPREFFILE_NO )
  141.             exit(1);
  142. #endif
  143.         FSpCreateResFile(&dirspec, 'Pyth', 'pref', 0);
  144.         prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  145.         if ( prefrh == -1 ) {
  146.             /* This "cannot happen":-) */
  147.             printf("Cannot create preferences file, error %d\n", ResError());
  148.             exit(1);
  149.         }
  150.         if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
  151.             printf("Cannot get FSSpec for application, error %d\n", err);
  152.             exit(1);
  153.         }
  154.         dirspec.name[0] = 0;
  155.         if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
  156.             printf("Cannot make alias to application directory, error %d\n", err);
  157.             exit(1);
  158.         }
  159.         AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
  160.         UpdateResFile(prefrh);
  161.  
  162.     } else {
  163.         UseResFile(prefrh);
  164.     }
  165.     return prefrh;
  166. }
  167.  
  168. /*
  169. ** Return the name of the Python directory
  170. */
  171. static char *
  172. PyMac_GetPythonDir()
  173. {
  174.     static int diditbefore = 0;
  175.     static char name[256] = {':', '\0'};
  176.     AliasHandle handle;
  177.     FSSpec dirspec;
  178.     Boolean modified = 0;
  179.     short oldrh, prefrh = -1, homerh;
  180.     
  181.     if ( diditbefore )
  182.         return name;
  183.         
  184.     oldrh = CurResFile();
  185.  
  186.     /* First look for an override in the application file */
  187.     UseResFile(PyMac_AppRefNum);
  188.     handle = (AliasHandle)Get1Resource('alis', PYTHONHOMEOVERRIDE_ID);
  189.     if ( handle != NULL ) {
  190.         homerh = PyMac_AppRefNum;
  191.     } else {   
  192.         /* Try to open preferences file in the preferences folder. */
  193.         prefrh = PyMac_OpenPrefFile();
  194.         handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
  195.         if ( handle == NULL ) {
  196.             (void)StopAlert(BADPREFFILE_ID, NULL);
  197.             diditbefore=1;
  198.             return ":";
  199.         }
  200.         homerh = prefrh;
  201.     }
  202.     /* It exists. Resolve it (possibly updating it) */
  203.     if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
  204.         (void)StopAlert(BADPREFFILE_ID, NULL);
  205.         diditbefore=1;
  206.         return ":";
  207.     }
  208.     if ( modified ) {
  209.            ChangedResource((Handle)handle);
  210.         UpdateResFile(homerh);
  211.     }
  212.     if ( prefrh != -1 ) CloseResFile(prefrh);
  213.     UseResFile(oldrh);
  214.  
  215.        if ( nfullpath(&dirspec, name) == 0 ) {
  216.            strcat(name, ":");
  217.     } else {
  218.          /* If all fails, we return the current directory */
  219.            printf("Python home dir exists but I cannot find the pathname!!\n");
  220.         name[0] = 0;
  221.         (void)getwd(name);
  222.     }
  223.     diditbefore = 1;
  224.     return name;
  225. }
  226.  
  227. #ifndef USE_BUILTIN_PATH
  228. static char *
  229. PyMac_GetPythonPath()
  230. {
  231.     FSSpec dirspec;
  232.     short oldrh, prefrh = -1;
  233.     char *rv;
  234.     int i, newlen;
  235.     Str255 pathitem;
  236.     int resource_id;
  237.     OSErr err;
  238.     Handle h;
  239.     
  240.     oldrh = CurResFile();
  241.     /*
  242.     ** This is a bit tricky. We check here whether the application file
  243.     ** contains an override. This is to forestall us finding another STR# resource
  244.     ** with "our" id and using that for path initialization
  245.     */
  246.     UseResFile(PyMac_AppRefNum);
  247.     SetResLoad(0);
  248.     if ( (h=Get1Resource('STR#', PYTHONPATHOVERRIDE_ID)) ) {
  249.         ReleaseResource(h);
  250.         resource_id = PYTHONPATHOVERRIDE_ID;
  251.     } else {
  252.         resource_id = PYTHONPATH_ID;
  253.     }
  254.     SetResLoad(1);
  255.     UseResFile(oldrh);
  256.     
  257.     /* Open the preferences file only if there is no override */
  258.     if ( resource_id != PYTHONPATHOVERRIDE_ID )
  259.         prefrh = PyMac_OpenPrefFile();
  260.     /* At this point, we may or may not have the preferences file open, and it
  261.     ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
  262.     ** exist we use the one from the application (the default).
  263.     ** We put an initial '\n' in front of the path that we don't return to the caller
  264.     */
  265.     if( (rv = malloc(2)) == NULL )
  266.         goto out;
  267.     strcpy(rv, "\n");
  268.  
  269.     for(i=1; ; i++) {
  270.         GetIndString(pathitem, resource_id, i);
  271.         if( pathitem[0] == 0 )
  272.             break;
  273.         if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
  274.             /* We have to put the directory in place */
  275.             char *dir = PyMac_GetPythonDir();
  276.             
  277.             newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
  278.             if( (rv=realloc(rv, newlen)) == NULL)
  279.                 goto out;
  280.             strcat(rv, dir);
  281.             /* Skip a colon at the beginning of the item */
  282.             if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
  283.                 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
  284.                 newlen--;
  285.             } else {
  286.                 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
  287.             }
  288.             rv[newlen-2] = '\n';
  289.             rv[newlen-1] = 0;
  290.         } else if ( pathitem[0] >= 14 && strncmp((char *)pathitem+1, "$(APPLICATION)", 14) == 0 ) {
  291.             /* This is the application itself */
  292.             char fullname[256];
  293.             
  294.             if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
  295.                 printf("Cannot get FSSpec for application, error %d\n", err);
  296.                 exit(1);
  297.             }
  298.             if ( nfullpath(&dirspec, fullname) != 0 ) {
  299.                 printf("Cannot convert application fsspec to path\n");
  300.                 exit(1);
  301.             }
  302.             newlen = strlen(rv) + strlen(fullname) + 2;
  303.             if( (rv=realloc(rv, newlen)) == NULL)
  304.                 goto out;
  305.             strcpy(rv+strlen(rv), fullname);
  306.             rv[newlen-2] = '\n';
  307.             rv[newlen-1] = 0;
  308.  
  309.         } else {
  310.             /* Use as-is */
  311.             newlen = strlen(rv) + (pathitem[0]) + 2;
  312.             if( (rv=realloc(rv, newlen)) == NULL)
  313.                 goto out;
  314.             memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
  315.             rv[newlen-2] = '\n';
  316.             rv[newlen-1] = 0;
  317.         }
  318.     }
  319.     if( strlen(rv) == 1) {
  320.         free(rv);
  321.         rv = NULL;
  322.     }
  323.     if ( rv ) {
  324.         rv[strlen(rv)-1] = 0;
  325.         rv++;
  326.     }
  327. out:
  328.     if ( prefrh != -1) CloseResFile(prefrh);
  329.     UseResFile(oldrh);
  330.     return rv;
  331. }
  332. #endif /* !USE_BUILTIN_PATH */
  333.  
  334. void
  335. PyMac_PreferenceOptions(PyMac_PrefRecord *pr)
  336. {
  337.     short oldrh, prefrh = -1;
  338.     Handle handle;
  339.     int size;
  340.     char *p;
  341.     
  342.     
  343.     oldrh = CurResFile();
  344.     
  345.     /* Attempt to load overrides from application */
  346.     UseResFile(PyMac_AppRefNum);
  347.     handle = Get1Resource('Popt', PYTHONOPTIONSOVERRIDE_ID);
  348.     UseResFile(oldrh);
  349.     
  350.     /* Otherwise get options from prefs file or any other open resource file */
  351.     if ( handle == NULL ) {
  352.         prefrh = PyMac_OpenPrefFile();
  353.         handle = GetResource('Popt', PYTHONOPTIONS_ID);
  354.     }
  355.     if ( handle == NULL ) {
  356.         return;
  357.     }
  358.     HLock(handle);
  359.     size = GetHandleSize(handle);
  360.     p = (char *)*handle;
  361.     
  362.     if ( size > POPT_INSPECT ) pr->inspect = p[POPT_INSPECT];
  363.     if ( size > POPT_VERBOSE ) pr->verbose = p[POPT_VERBOSE];
  364.     if ( size > POPT_SUPPRESS ) pr->suppress_print = p[POPT_SUPPRESS];
  365.     if ( size > POPT_UNBUFFERED ) pr->unbuffered = p[POPT_UNBUFFERED];
  366.     if ( size > POPT_DEBUGGING ) pr->debugging = p[POPT_DEBUGGING];
  367.     if ( size > POPT_KEEPNORM ) pr->keep_normal = p[POPT_KEEPNORM];
  368.     if ( size > POPT_KEEPERR ) pr->keep_error = p[POPT_KEEPERR];
  369.     if ( size > POPT_NOINTOPT ) pr->nointopt = p[POPT_NOINTOPT];
  370.     if ( size > POPT_NOARGS ) pr->noargs = p[POPT_NOARGS];
  371.     
  372.     HUnlock(handle);
  373.  
  374.        if ( prefrh != -1) CloseResFile(prefrh);
  375.     UseResFile(oldrh);
  376. }
  377.  
  378. #ifdef USE_GUSI
  379. void
  380. PyMac_SetGUSIOptions()
  381. {
  382.     Handle h;
  383.     short oldrh, prefrh = -1;
  384.     
  385.     oldrh = CurResFile();
  386.     
  387.     /* Try override from the application resource fork */
  388.     UseResFile(PyMac_AppRefNum);
  389.     h = Get1Resource('GU\267I', GUSIOPTIONSOVERRIDE_ID);
  390.     UseResFile(oldrh);
  391.     
  392.     /* If that didn't work try nonoverride from anywhere */
  393.     if ( h == NULL ) {
  394.         prefrh = PyMac_OpenPrefFile();
  395.         h = GetResource('GU\267I', GUSIOPTIONS_ID);
  396.     }
  397.     if ( h ) GUSILoadConfiguration(h);
  398.        if ( prefrh != -1) CloseResFile(prefrh);
  399.     UseResFile(oldrh);
  400. }
  401. #endif /* USE_GUSI */    
  402.